# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
__docformat__ = "restructuredtext en"

from .. import formlib as layout

LEFT, RIGHT = layout.LEFT, layout.RIGHT


class BraidSmallLayout(layout.Layout):
    """
    - row [4 over 2 cols E, 4 over 2 cols  W braid, no offset]
    - reserve [1 N 1 S row E W braid, no offset]
    - braid [1 N, braid offset]
    - talon [1 E foundation, no offset]
    - waste [1 E talon, no offset]
    - foundation [8 over 2 col E, no offset]

    :cvar func _offset: dict('ycards': value)
    """
    _offset = lambda self, cards: {'ycards': cards}

    def create(self, rows, bases=None, reserves=4, braidcards=20, texts=False,
               **kw):
        l, s = self, self.s
        bases = tuple(bases) if isinstance(bases, (list, tuple)) else l.SUITS
        f_rows = min(5, l.NSUIT if bases == l.SUITS else len(bases))
        ix = l.size.width + l.XM
        reserves /= 4
        rows /=2

        def row_reserve_block(x, y):
            res_x = x + reserves * l.HXS
            l._set_horz_reserves(res_x, y, reserves, reserve_texts=False,
                                 anchor='n')
            y += l.YS
            l._set_rows(x, y, rows=rows, ncols=2)
            y = s['rows'][-1].y + l.YS
            l._set_horz_reserves(res_x, y, reserves, reserve_texts=False,
                                 anchor='n')
        row_reserve_block(ix, l.YM)
        x = l.size.width + l.HXS
        s['braid'].append(l._create_stack(x, l.YM))
        s['braid'][-1].set_offset((l.XOFFSET, -l.XOFFSET, 0,), l.YOFFSET)
        self.size = layout.canvasSize(max(self.size.width, l.size.width + 2 *
                                      l.XS), max(self.size.height,
                                      l._get_stack_height(braidcards),))
        row_reserve_block(l.size.width, l.YM)
        l._set_horz_talon(l.size.width, (l.size.height - l.XS) / 2,
                          anchor='n', align=LEFT, texts=True, wastecards=0)
        l._set_vert_foundations(l.size.width, l.YM, nrows=f_rows, bases=bases)
        s['talon'].set_rounds(anchor='nn')

    def defaultStackGroups(self):
        """
        defaultStackGroups() -> None

        Set default for groups.
        """
        super(BraidSmallLayout, self).defaultStackGroups()
        sg, s = self.game.sg, self.game.s
        sg['dropstacks'] += s['braid']


class BraidLargeLayout(layout.Layout):
    """
      - row [5 vert E reserve, 5 vert W reserve, no offset]
      - reserve [5 vert E foundation, 5 vert W foundation,, no offset]
      - braid [2 N, braid offset]
      - talon [1 S foundation, no offset]
      - waste [1 E talon, no offset]
      - foundation [5 vert W, 5 vert E, no offset]

    :cvar func _offset: dict('ycards': value)
    """
    _offset = lambda self, cards: {'ycards': cards}

    def create(self, bases=None, braidcards=20, texts=False, **kw):
        l, s = self, self.s
        bases = bases if type(bases) in (list, tuple) else l.SUITS
        bases.sort()
        ix = l.size.width + l.XM
        hf_rows = len(bases) / 2
        # W half vert foundations
        l._set_horz_foundations(x=ix, y=l.YM, ncols=l.NDECKS,
                                bases=bases[:hf_rows])
        l._set_vert_reserves(l.size.width, l.YM, l.NSUIT / 2,
                             reserve_texts=False, anchor='n')
        l._set_rows(l.size.width, l.YM, l.NSUIT / 2, ncols=1)
        x = l.size.width + l.HXS
        s['braid'].append(l._create_stack(x, l.YM))
        s['braid'][-1].set_offset((l.XOFFSET, -l.XOFFSET, 0,), 0)
        x = l.size.width + 2 * l.XS
        s['braid'].append(l._create_stack(x, l.YM))
        s['braid'][-1].set_offset((l.XOFFSET, -l.XOFFSET, 0,), 0)
        l.size = layout.canvasSize(max(l.size.width, l.size.width + 7 *
                                   l.HXS), max(l.size.height,
                                   l._get_stack_height(braidcards),))
        l._set_rows(l.size.width, l.YM, l.NSUIT / 2, ncols=1)
        l._set_vert_reserves(l.size.width, l.YM, l.NSUIT / 2,
                             reserve_texts=False, anchor='n')
        l._set_horz_foundations(x=l.size.width, y=l.YM, ncols=l.NDECKS,
                                bases=bases[hf_rows:])
        l._set_horz_talon((l.size.width - 2 * l.XS) / 2,
                           l.size.height + l.TEXT_HEIGHT,
                           anchor='s', align=LEFT, texts=True, wastecards=0)
        s['talon'].set_rounds(anchor='ss')

    def defaultStackGroups(self):
        """
        defaultStackGroups() -> None

        Set default for groups.
        """
        super(BraidSmallLayout, self).defaultStackGroups()
        sg, s = self.game.sg, self.game.s
        sg['dropstacks'] += s['braid']


class BackboneLayout(layout.Layout):
    """
      - row [5 vert E reserve, 5 vert W reserve, no offset]
      - reserve [5 vert E foundation, 5 vert W foundation,, no offset]
      - braid [2 N, braid offset]
      - talon [1 S foundation, no offset]
      - waste [1 E talon, no offset]
      - foundation [5 vert W, 5 vert E, no offset]

    :cvar func _offset: dict('ycards': value)
    """
    _offset = lambda self, cards: {'ycards': cards}

    def create(self, rows, playcards=15, bases=None, holdcards=0,
               align=LEFT, texts=False, **kw):
        l, s = self, self.s
        ncols = ncols or rows
        # set foundation base caps
        bases = bases if type(bases) in (list, tuple) else l.SUITS
        f_cols = min(5, l.NSUIT if bases is l.SUITS else len(bases))
        f_rows = len(bases) / 2
        max_rows = max(f_cols * 2, rows)
        right = lambda p: (max_rows / 2 - p) * l.XS
        ix = l.size.width + l.XM
        l._set_horz_foundations(x=ix + right(f_cols), y=l.YM, ncols=f_cols,
                                bases=bases[:f_rows])
        dy = l.size.height
        l._set_rows(x=ix + right(rows / 2), y=dy, rows=rows / 2, ncols=rows / 2,
                   ycards=playcards)
        l._set_horz_reserves(x=l.size.width, y=l.XM, reserves=2,
                             reserve_texts=False, anchor='n',
                             ycards=holdcards)
        s['reserves'].append(l._create_stack(x=l.size.width - 3 * l.HXS,
                                          y=l.YM + holdcards * l.YOFFSET))
        dx = l.size.width
        l._set_horz_foundations(x=dx, y=l.YM, ncols=f_cols,
                                bases=bases[f_rows:])
        l._set_rows(x=dx, y=dy, rows=rows / 2,  ncols=rows / 2,
                   ycards=playcards)
        l._set_horz_talon((l.size.width - 2 * l.XS) / 2,
                           l.size.height + l.TEXT_HEIGHT,
                           anchor='n', align=align, texts=texts, wastecards=0)
        s.talon.set_rounds(anchor='nn')